package indi.dbfmp.oio.gateway.filter;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.plumelog.core.TraceId;
import com.plumelog.core.constant.LogMessageConstant;
import indi.dbfmp.oio.gateway.constants.OioLogPattern;
import indi.dbfmp.oio.gateway.constants.OioReqHeader;
import indi.dbfmp.web.common.dto.CommonResult;
import io.micrometer.core.instrument.Timer;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * <p>
 *  追踪码过滤器
 * </p>
 *
 * @author dbfmp
 * @name: TraceIdFilter
 * @since 2021/4/27 下午10:56
 */
@Slf4j
@Order(Integer.MIN_VALUE)
@Component
public class TraceIdFilter implements WebFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {

        String reqId = serverWebExchange.getRequest().getHeaders().getFirst(OioReqHeader.REQUEST_ID);
        if (StrUtil.isBlank(reqId)) {
            reqId = IdUtil.fastSimpleUUID();
            ServerHttpRequest request = serverWebExchange.getRequest().mutate().header(OioReqHeader.REQUEST_ID, reqId).build();
            serverWebExchange = serverWebExchange.mutate().request(request).build();
        }
        //设置TraceID值，不埋此点链路ID就没有
        TraceId.logTraceID.set(reqId);
        try {
            MDC.put(LogMessageConstant.TRACE_ID,reqId);
            log.info("请求流水号");
            return webFilterChain.filter(serverWebExchange).doOnSuccess((x)->MDC.clear());
        }catch (Exception e) {
            log.error("追踪码过滤器异常",e);
            ServerHttpResponse response = serverWebExchange.getResponse();
            response.setStatusCode(HttpStatus.OK);
            response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
            String body= JSONUtil.toJsonStr(CommonResult.failed("服务开小差了，稍后再试试吧"));
            DataBuffer buffer =  response.bufferFactory().wrap(body.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(buffer));
        }
    }
}
